home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
listings
/
v_12_03
/
letters
/
allocdma.c
< prev
Wrap
Text File
|
1994-01-18
|
2KB
|
69 lines
@CSOURCE8 = #define BYTE char<R>
typedef unsigned int WORD;<R>
typedef unsigned long BIG;<R>
<R>
#define JUNKCHUNK (128)<R>
/* how we will search for physical<R>
boundaries. (Must be >>= sizeof(JUNK)) */<R>
<R>
/* produce a big physical address. This<R>
is "large" mode code; " FP_SEG" etc. are<R>
Turbo C macros which extract the two<R>
parts of an 80x86-style segment-offset<R>
pointer. */<R>
<R>
#define PHYSICAL(x) ((BIG)((((BIG)<R>
(FP_SEG(x)))<<<<4)+((BIG)FP_OFF(x))))<R>
<R>
typedef struct JK<R>
struct JK *next;<R>
} JUNK;<R>
<R>
_f void *mustallocdma(WORD size) {<R>
BYTE *a;<R>
JUNK root, *next, *p;<R>
BIG leftover;<R>
WORD junksize;<R>
root.next=NULL;<R>
next=&root;<R>
<R>
while(1) {<R>
a=mustalloc(size);<R>
/* mustalloc==malloc,<R>
but aborts if failure;<R>
the function exits this<R>
way or via the break below<R>
at success.*/<R>
<R>
if (<R>
(leftover=(PHYSICAL(a) & 0xffff)) +<R>
((BIG) size)<R>
>>= Ox10000) {<R>
/* it's no good. */<R>
if (<R>
(junksize = 0x10000-leftover)<R>
<< JUNKCHUNK)<R>
junksize=JUNKCHUNK;<R>
/* avoid endless<R>
teeny-tiny manipulations. */<R>
<R>
free(a);<R>
next->>next=mustalloc(junksize);<R>
next=next->>next;<R>
}<R>
else<R>
break; /* success! */<R>
}<R>
/* free debris. */<R>
next=root.next;<R>
while(next)<R>
p=next;<R>
next=next->>next;<R>
free(p);<R>
}<R>
return a;<R>
}<R>
<R>
/* End of File */